package edu.ccut.saturn.studio.menuitem.model;

import java.util.LinkedList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Node;


import edu.ccut.saturn.studio.core.util.xml.SaturnW3CUtil;

public class MenuItemModel {

	public static final String MENUITEM_ATTRIBUTE_PARENT_ID = "parentId";

	public static final String MENUITEM_ATTRIBUTE_ORDER = "order";

	public static final String MENUITEM_ATTRIBUTE_PATH = "path";

	public static final String MENUITEM_ATTRIBUTE_LABEL = "label";

	public static final String MENUITEM_ATTRIBUTE_ID = "id";

	public static final String MENUITEMS_ELEMENT_MENUITEM = "menuItem";

	private Menu menu;
	
	private Document document;

	public MenuItemModel(Document document) {
		this.document = document;
	}

	public Document getDocument() {
		return document;
	}

	private Node getRootNode() {
		return this.document.getDocumentElement();
	}

	public Menu getMenu() {
		if (menu == null) {
			List<Node> childern = SaturnW3CUtil.getChildrenByName(this
					.getRootNode(), MENUITEMS_ELEMENT_MENUITEM);

			this.menu = new Menu();
			
			if (childern != null) {
				for (Node menuItemNode : childern) {
					loadMenuItem(menuItemNode, this.menu.getRoot());
				}
			}
		}

		return menu;
	}

	private void loadMenuItem(Node menuItemNode, MenuItem parent) {
		String id = SaturnW3CUtil.getNodeAttributeValue(menuItemNode,
				MENUITEM_ATTRIBUTE_ID);
		String label = SaturnW3CUtil.getNodeAttributeValue(menuItemNode,
				MENUITEM_ATTRIBUTE_LABEL);
		String path = SaturnW3CUtil.getNodeAttributeValue(menuItemNode,
				MENUITEM_ATTRIBUTE_PATH);
		String order = SaturnW3CUtil.getNodeAttributeValue(menuItemNode,
				MENUITEM_ATTRIBUTE_ORDER);
		String parentId = SaturnW3CUtil.getNodeAttributeValue(menuItemNode,
				MENUITEM_ATTRIBUTE_PARENT_ID);

		MenuItem menuItem = new MenuItem();

		menuItem.setParentId(parentId);
		menuItem.setId(id);
		menuItem.setLabel(label);
		menuItem.setPath(path);
		menuItem.setOrder(order);
		menuItem.setParent(parent);

		parent.addChild(menuItem);

		List<Node> childNodes = SaturnW3CUtil.getChildrenByName(menuItemNode,
				MENUITEMS_ELEMENT_MENUITEM);

		if (childNodes != null) {
			for (Node childNode : childNodes) {
				loadMenuItem(childNode, menuItem);
			}
		}
	}
	
	public void deleteMenuItem(MenuItem menuItem) {
		Node menuItemNode = this.getMenuItemNodeById(menuItem.getId());
		
		Node parentMenuItem = menuItemNode.getParentNode();
		
		parentMenuItem.removeChild(menuItemNode);
		
		SaturnW3CUtil.format(parentMenuItem);
	}

	public void addMenuItem(String parentId, MenuItem child) {
		Node menuItemNode = this.getMenuItemNodeById(parentId);
		
		if (menuItemNode == null) {
			menuItemNode = this.getRootNode();
		}
		
		Node newMenuItemNode = SaturnW3CUtil.createChildNode(menuItemNode, MENUITEMS_ELEMENT_MENUITEM, null);
		
		
		SaturnW3CUtil.createAttribute(newMenuItemNode, MENUITEM_ATTRIBUTE_ID, child.getId());
		SaturnW3CUtil.createAttribute(newMenuItemNode, MENUITEM_ATTRIBUTE_LABEL, child.getLabel());
		SaturnW3CUtil.createAttribute(newMenuItemNode, MENUITEM_ATTRIBUTE_ORDER, child.getOrder());
		SaturnW3CUtil.createAttribute(newMenuItemNode, MENUITEM_ATTRIBUTE_PARENT_ID, child.getParentId());
		SaturnW3CUtil.createAttribute(newMenuItemNode, MENUITEM_ATTRIBUTE_PATH, child.getPath());
		
		SaturnW3CUtil.format(menuItemNode);
	}

	public Node getMenuItemNodeById(String id) {
		List<Node> menuItems = SaturnW3CUtil.getChildrenByName(this.getRootNode(),
				MENUITEMS_ELEMENT_MENUITEM);
		
		LinkedList<Node> stack = new LinkedList<Node>();
		stack.addAll(menuItems);
		
		while (!stack.isEmpty()) {
			Node menuItemNode = (Node) stack.removeFirst();
			
			String menuItemId = SaturnW3CUtil.getNodeAttributeValue(menuItemNode, MENUITEM_ATTRIBUTE_ID);
			if (menuItemId.equals(id)) {
				return menuItemNode;
			} else {
				List<Node> children = SaturnW3CUtil.getChildrenByName(menuItemNode, MENUITEMS_ELEMENT_MENUITEM);

				if (children != null) {
					stack.addAll(children);
				}
			}
		}

		return null;
	}

	public void changeMenuItemAttribute(String id, String name, String value) {
		Node node = this.getMenuItemNodeById(id);
		
		SaturnW3CUtil.createAttribute(node, name, value);
	}

}
